﻿using BCAMap.AMap;
using BCCommon;
using BCCommon.Enums;
using BCCommon.Enums.Driver;
using BCCommon.Extensions;
using BCCommon.TMS.Order;
using BCData.TMS.Order.Order;
using BCData.TMS.Order.OrderAssignRecord;
using BCData.TMS.Order.OrderPool;
using BCData.TMS.VehicleIgnoreOrderAssignRecord;
using BCDto.Sim.Admin.Admin;
using BCDto.TMS.Driver;
using BCDto.TMS.Order;
using BCDto.TMS.Order.OrderPool;
using BCEntity.Common.EntityNameConst;
using BCEntity.TMS.Order.OrderAssignRecord;
using BCEntity.TMS.VehicleIgnoreOrderAssignRecord;
using BCService.Common.PushMessage.PushMessageSend;
using BCService.Sim.Admin.Admin;
using BCService.Sim.Company.Department;
using BCService.TMS.Agent.AgentAreaRecord;
using BCService.TMS.Driver;
using BCService.TMS.Location.Driver;
using BCService.TMS.Order.Order;
using BCService.TMS.Order.OrderExtention;
using BCService.TMS.VehicleTypeService;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BCService.TMS.Order
{
    public class OrderPoolService : IOrderPoolService
    {
        private readonly IDatabaseContext database;
        private readonly IDriverService driverService;
        private readonly IOrderPoolData orderPoolData;
        private readonly IOrderData orderData;
        private readonly IOrderProcessService orderService;
        private readonly IVehicleTypeService vehicleTypeService;
        private readonly IRedisService redisService;
        private readonly IPushMessageSendService pushMessageSendService;
        private readonly IDriverLocationService driverLocationService;
        private readonly IAMapUtils aMapUtils;
        private readonly IAdminService adminService;
        private readonly IDepartmentService departmentService;
        private readonly IAgentAreaRecordService agentAreaRecordService;
        private readonly IOrderAssignRecordData orderAssignRecordData;
        private readonly IOrderExtentionService orderExtentionService;
        private readonly IVehicleIgnoreOrderAssignRecordData vehicleIgnoreOrderAssignRecordData;
        public OrderPoolService(IDatabaseContext database, IDriverService driverService,
            IOrderPoolData orderPoolData,
            IOrderData orderData,
            IOrderProcessService orderService,
            IVehicleTypeService vehicleTypeService,
            IRedisService redisService,
            IPushMessageSendService pushMessageSendService,
            IDriverLocationService driverLocationService,
            IAMapUtils aMapUtils,
            IAdminService adminService,
            IDepartmentService departmentService,
            IAgentAreaRecordService agentAreaRecordService,
            IOrderAssignRecordData orderAssignRecordData,
            IOrderExtentionService orderExtentionService,
            IVehicleIgnoreOrderAssignRecordData vehicleIgnoreOrderAssignRecordData)
        {
            this.database = database;
            this.driverService = driverService;
            this.orderPoolData = orderPoolData;
            this.orderService = orderService;
            this.orderData = orderData;
            this.vehicleTypeService = vehicleTypeService;
            this.redisService = redisService;
            this.pushMessageSendService = pushMessageSendService;
            this.driverLocationService = driverLocationService;
            this.aMapUtils = aMapUtils;
            this.adminService = adminService;
            this.departmentService = departmentService;
            this.agentAreaRecordService = agentAreaRecordService;
            this.orderAssignRecordData = orderAssignRecordData;
            this.orderExtentionService = orderExtentionService;
            this.vehicleIgnoreOrderAssignRecordData = vehicleIgnoreOrderAssignRecordData;
        }

        #region 订单指派
        public bool AssignVehicle(long[] orderIds, long driverId, int? distance, AdminDto adminDto)
        {
            var driverDto = this.driverService.GetDriverById(driverId);
            if (driverDto == null)
            {
                throw new ArgumentException("车辆信息不存在");
            }

            return AssignVehicle(driverDto, orderIds, distance, adminDto);
        }

        public bool AssignVehicle(string vehicleNo, long[] orderIds, int? distance, AdminDto adminDto)
        {
            var driverDto = this.driverService.GetDriverByVehicleNo(vehicleNo);
            if (driverDto == null)
            {
                throw new ArgumentException("车辆信息不存在");
            }
            return AssignVehicle(driverDto, orderIds, distance, adminDto);
        }

        private bool AssignVehicle(DriverDto driverDto, long[] orderIds, int? distance, AdminDto adminDto)
        {
            if (driverDto.WorkingStatus == DriverWorkingStatus.Stopped)
            {
                throw new ArgumentException("车辆已停运!");
            }
            if (driverDto.WorkingStatus == DriverWorkingStatus.Resting)
            {
                throw new ArgumentException("司机休息中!");
            }

            database.BeginTransaction();
            List<OrderDto> orderDtos = new List<OrderDto>();
            foreach (long orderId in orderIds)
            {
                var order = this.orderService.GetOrder(orderId);
                if (order.AgentRecordId != adminDto.AgentRecord.AgentRecordId)
                {
                    throw new ArgumentException(string.Format("订单编号:{0}，此订单您无权指派!", order.OrderNo));
                }

                OrderStatus[] orderStatuses = new OrderStatus[] { OrderStatus.Cancel, OrderStatus.Acceptance, OrderStatus.Arrived, OrderStatus.Complete, OrderStatus.Pickup, OrderStatus.Transporting };
                if (order.OrderStatus.In(orderStatuses))
                {
                    this.CloseOrder(orderId);
                    throw new ArgumentException(string.Format("订单编号:{0}，司机已接单，无法重新指派!", order.OrderNo));
                }

                orderDtos.Add(order);

                if (!this.orderPoolData.UpdateStatusProcessing(adminDto.AdminId, adminDto.FullName, orderId, driverDto.DriverId, driverDto.VehicleNo, this.GetDistance(orderId, driverDto.VehicleNo)).GetAwaiter().GetResult())
                {
                    throw new ArgumentException("订单指派失败!");
                }

                OrderAssignRecordEntity orderAssignRecordEntity = new OrderAssignRecordEntity()
                {
                    OrderId = orderId,
                    AdminId = adminDto.AdminId,
                    CompanyId = adminDto.CompanyId,
                    DepartmentId = adminDto.Department.DepartmentId,
                    Reason = "已指派",
                    IsAssign = true,
                    VehicleNo = driverDto.VehicleNo,
                    DriverId = driverDto.DriverId,
                    DriverName = driverDto.Name,
                    AssignEditerId = adminDto.AdminId,
                    AssignEditer = adminDto.FullName,
                    AssignTime = DateTime.Now,
                    AssignTimeOut = DateTime.Now.AddMinutes(20)
                };

                var entity = orderAssignRecordData.InsertAsync(orderAssignRecordEntity).GetAwaiter().GetResult();

                if (entity == null)
                {
                    throw new ArgumentException(string.Format("订单编号：{0},订单指派异常!", order.OrderNo));
                }

                if (!this.orderExtentionService.UpdateOrderStatusDispatching(order.OrderNo))
                {
                    throw new ArgumentException("订单指派失败!");
                }
                this.redisService.DeleteAsync(string.Format("{0}:OrderId={1}", EntityNameConst.OrderEntity, orderId));
                this.pushMessageSendService.PushMessageForOrder(orderId, PushMessageType.AssignedVehicle);
            }
            this.database.Commit();
            return true;
        }
        #endregion 

        public void IgnoreOrderAssign(long driverId, long orderId)
        {
            var result = this.orderPoolData.Get(orderId).GetAwaiter().GetResult();
            if (result.DriverId != driverId)
            {
                throw new ArgumentException("无权忽略指派给他人的订单");
            }
            var orderEntity = this.orderData.GetEntity(orderId).GetAwaiter().GetResult();
            if (orderEntity.OrderStatus != OrderStatus.Dispatching && orderEntity.OrderStatus != OrderStatus.PlaceOrder)
            {
                throw new ArgumentException("此订单已在进行中，无法忽略");
            }
            //TODO:需要增加司机最大每日取消订单次数检查

            if (!this.orderPoolData.ClearOrderAssign(orderId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("订单忽略失败!");
            }

            this.vehicleIgnoreOrderAssignRecordData.Add(new VehicleIgnoreOrderAssignRecordEntity
            {
                DriverId = driverId,
                VehicleNo = result.VehicleNo,
                OrderId = orderId,
                OrderNo = orderEntity.OrderNo
            });
        }

        public void ClearOrderAssign(long orderId)
        {
            //检查订单是否已经被接单，防止订单已被接造成的误差
            var orderEntity = this.orderData.GetEntity(orderId).Result;

            if (orderEntity == null)
            {
                throw new ArgumentException("订单信息不存在");
            }

            OrderStatus[] orderStatuses = new OrderStatus[] { OrderStatus.Cancel, OrderStatus.Acceptance, OrderStatus.Arrived, OrderStatus.Complete, OrderStatus.Pickup, OrderStatus.Transporting };

            if (orderEntity.OrderStatus.In(orderStatuses))
            {
                this.CloseOrder(orderId);
            }
            else
            {
                this.orderPoolData.ClearOrderAssign(orderId);
            }
        }

        public void CloseOrder(long orderId)
        {
            this.orderPoolData.UpdateStatusDone(orderId, null);
        }

        public PageableList<OrderPoolDto> GetOrders(AdminDto adminDto, string provinceCode, string cityCode, string countyCode, OrderAssignHandleStatus? handleStatus, long? vehicleId, DateTime? start, DateTime? end, bool? ascending, int pageIndex, int pageSize)
        {
            var (data, count) = this.orderPoolData.Query(adminDto!=null?adminDto.AdminId:new Nullable<long>(), provinceCode, cityCode, countyCode, handleStatus, vehicleId, start, end, ascending, pageIndex, pageSize).GetAwaiter().GetResult();
            var list = data.As<IEnumerable<OrderPoolDto>>();
            List<OrderPoolDto> orderPools = new List<OrderPoolDto>();
            foreach (var orderPool in list)
            {
                var orderPoolDto = this.orderService.GetOrder(orderPool.OrderId).As<OrderPoolDto>();
                orderPoolDto.AssignTimeOut = orderPool.AssignTimeOut;
                orderPoolDto.AssignStatus = orderPool.AssignStatus;
                orderPoolDto.Editer = orderPool.Editer;
                orderPoolDto.UpdateTime = orderPool.UpdateTime;
                orderPoolDto.EndTime = orderPool.EndTime;
                orderPoolDto.IsTimeOut = orderPool.IsTimeOut;
                orderPoolDto.TimeOutLevel = orderPool.TimeOutLevel;
                orderPoolDto.DriverName = orderPool.DriverName;
                orderPoolDto.DriverPhone = orderPool.DriverPhone;
                orderPoolDto.DriverId = orderPool.DriverId;
                orderPoolDto.VehicleNo = orderPool.VehicleNo;
                orderPoolDto.AssignRecordExists = orderPool.AssignRecordExists;
                if (orderPoolDto.Distance.HasValue)
                {
                    orderPoolDto.Distance = Math.Round(orderPoolDto.Distance.Value / 1000, 2, MidpointRounding.AwayFromZero);
                }
                orderPools.Add(orderPoolDto);
            }
            return new PageableList<OrderPoolDto>()
            {
                Items = orderPools,
                Count = count
            };
        }
        public OrderPoolDto GetOrder(long orderId)
        {
            var orderPoolEntity = this.orderPoolData.Get(orderId).GetAwaiter().GetResult();
            var orderPoolDto = this.orderService.GetOrder(orderPoolEntity.OrderId).As<OrderPoolDto>();
            orderPoolDto.AssignTimeOut = orderPoolEntity.AssignTimeOut;
            orderPoolDto.AssignStatus = orderPoolEntity.AssignStatus;
            orderPoolDto.Editer = orderPoolEntity.Editer;
            orderPoolDto.UpdateTime = orderPoolEntity.UpdateTime;
            orderPoolDto.EndTime = orderPoolEntity.EndTime;
            orderPoolDto.IsTimeOut = orderPoolEntity.IsTimeOut;
            orderPoolDto.TimeOutLevel = orderPoolEntity.TimeOutLevel;
            if (orderPoolDto.Distance.HasValue)
            {
                orderPoolDto.Distance = Math.Round(orderPoolDto.Distance.Value / 1000, 2, MidpointRounding.AwayFromZero);
            }
            return orderPoolDto;
        }
        private double GetDistance(long orderId, string vehicleNo)
        {
            OrderDto orderDto = this.orderService.GetOrder(orderId);
            if (orderDto == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            if (!orderDto.OrderExtentionInfo.Any())
            {
                throw new ArgumentException("订单地址信息不存在");
            }
            int minIndex = orderDto.OrderExtentionInfo.Min(p => p.EndIndex);
            if (orderDto.OrderExtentionInfo.Count(p => p.EndIndex == minIndex) > 1)
            {
                throw new ArgumentException("订单本身存在问题，存在多个装货地，且无法确定准确的首个装货地址");
            }
            var orderExtentionInfo = orderDto.OrderExtentionInfo.Single(p => p.EndIndex == minIndex);
            var locationCurrentlyVehicleEntity = this.driverLocationService.GetDriverLocationInfo(vehicleNo.Trim());
            //if (locationCurrentlyVehicleEntity == null)
            //{
            //    locationCurrentlyVehicleEntity = this.locationCurrentlyVehicleAppMongoData.Get(vehicleNo.Trim()).GetAwaiter().GetResult();
            //    if (locationCurrentlyVehicleEntity == null)
            //    {
            //        throw new ArgumentException("车辆不在线");
            //    }
            //}
            double dis = CoordinateUtils.CoordinateDifference(locationCurrentlyVehicleEntity.Longitude, locationCurrentlyVehicleEntity.Latitude, orderExtentionInfo.EndLongitude, orderExtentionInfo.EndLatitude);

            return dis / 1000;
        }

        //public bool IsAdministratorRole(long adminId)
        //{
        //    var adminEntities = orderPoolData.GetAdministratorRole().GetAwaiter().GetResult();
        //    if (adminEntities == null && adminEntities.Count() <= 0)
        //        return false;
        //    if (adminEntities.Count(s => s.AdminId == adminId) > 0)
        //        return true;
        //    else
        //        return false;
        //}

        //public PageableList<OrderPoolDto> GetOrderPoolStatistics(AdminDto adminDto, DateTime? start, DateTime? end, OrderAssignHandleStatus? assignStatus, int pageIndex, int pageSize)
        //{
        //    List<long> adminIds = new List<long>();
        //    IEnumerable<OrderPoolEntity> orderPoolList = null;
        //    int orderPoolListCount = 0;
        //    if (adminDto.IsSystemAccount || this.IsAdministratorRole(adminDto.AdminId))
        //    {
        //        (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(null, null, null, start, end, assignStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //    }
        //    else if (adminDto.IsMain)
        //    {
        //        if (assignStatus.HasValue)
        //        {
        //            #region
        //            if (assignStatus.Value == OrderAssignHandleStatus.Pending)
        //            {
        //                (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(adminDto.CompanyId, null, null, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //            }
        //            else
        //            {
        //                var adminEntityList = this.orderPoolData.GetIsMainAdminIds(adminDto.CompanyId).GetAwaiter().GetResult();
        //                if (adminEntityList.Any())
        //                {
        //                    adminIds = adminEntityList.Select(p => p.AdminId).ToList();
        //                    (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(null, null, adminIds, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //                }
        //                else
        //                {
        //                    adminIds.Add(adminDto.AdminId);
        //                    (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(null, null, adminIds, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //                }
        //            }
        //            #endregion
        //        }
        //        else
        //        {
        //            #region
        //            var adminEntityList = this.orderPoolData.GetIsMainAdminIds(adminDto.CompanyId).GetAwaiter().GetResult();
        //            if (adminEntityList.Any())
        //            {
        //                adminIds = adminEntityList.Select(p => p.AdminId).ToList();
        //                (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(adminDto.CompanyId, null, adminIds, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //            }
        //            else
        //            {
        //                adminIds.Add(adminDto.AdminId);
        //                (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(null, null, adminIds, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //            }
        //            #endregion
        //        }
        //    }
        //    else
        //    {
        //        if (assignStatus.HasValue)
        //        {
        //            #region
        //            if (assignStatus.Value == OrderAssignHandleStatus.Pending)
        //            {
        //                (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(null, adminDto.Department.DepartmentId, null, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //            }
        //            else
        //            {
        //                //查询是否是部门负责人
        //                var departmentEntity = this.departmentData.GetById(adminDto.Department.DepartmentId).GetAwaiter().GetResult();
        //                if (departmentEntity != null)
        //                {
        //                    if (departmentEntity.PrincipalAdminId == adminDto.AdminId)
        //                    {
        //                        var departmentStaffEntityList = this.orderPoolData.GetPrincipalAdminIdsAsync(adminDto.Department.DepartmentId).GetAwaiter().GetResult();
        //                        if (departmentStaffEntityList.Any())
        //                        {
        //                            adminIds = departmentStaffEntityList.Select(p => p.AdminId).ToList();
        //                            (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(null, null, adminIds, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //                        }
        //                        else
        //                        {
        //                            adminIds.Add(adminDto.AdminId);
        //                            (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(null, null, adminIds, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //                        }
        //                    }
        //                    else
        //                    {
        //                        adminIds.Add(adminDto.AdminId);
        //                        (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(null, null, adminIds, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //                    }
        //                }
        //                else
        //                {
        //                    adminIds.Add(adminDto.AdminId);
        //                    (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(null, null, adminIds, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //                }
        //            }
        //            #endregion
        //        }
        //        else
        //        {
        //            #region
        //            //查询是否是部门负责人
        //            var departmentEntity = this.departmentData.GetById(adminDto.Department.DepartmentId).GetAwaiter().GetResult();
        //            if (departmentEntity != null)
        //            {
        //                if (departmentEntity.PrincipalAdminId == adminDto.AdminId)
        //                {
        //                    var departmentStaffEntityList = this.orderPoolData.GetPrincipalAdminIdsAsync(adminDto.Department.DepartmentId).GetAwaiter().GetResult();
        //                    if (departmentStaffEntityList.Any())
        //                    {
        //                        adminIds = departmentStaffEntityList.Select(p => p.AdminId).ToList();
        //                        (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(null, adminDto.Department.DepartmentId, adminIds, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //                    }
        //                    else
        //                    {
        //                        adminIds.Add(adminDto.AdminId);
        //                        (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(null, null, adminIds, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //                    }
        //                }
        //                else
        //                {
        //                    adminIds.Add(adminDto.AdminId);
        //                    (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(null, null, adminIds, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //                }
        //            }
        //            else
        //            {
        //                adminIds.Add(adminDto.AdminId);
        //                (orderPoolList, orderPoolListCount) = this.orderPoolData.GetOrderPoolStatisticsAsync(null, null, adminIds, start, end, assignStatus, communicateStatus, pageIndex, pageSize).GetAwaiter().GetResult();
        //            }
        //            #endregion
        //        }
        //    }

        //    return new PageableList<OrderPoolDto>()
        //    {
        //        Count = orderPoolListCount,
        //        Items = orderPoolList.As<List<OrderPoolDto>>()
        //    };
        //}

        public PageableList<OrderPoolDto> GetDriverOrders(OrderAssignHandleStatus? processing, long driverId, int pageIndex, int pageSize)
        {
            var entities = this.orderPoolData.QueryDriverOrders(processing, driverId, pageIndex, pageSize).GetAwaiter().GetResult();
            IEnumerable<OrderPoolDto> list = entities.Item1.As<IEnumerable<OrderPoolDto>>();
            List<OrderPoolDto> orderPools = new List<OrderPoolDto>();
            foreach (var orderPool in list)
            {
                var orderPoolDto = this.orderService.GetOrder(orderPool.OrderId).As<OrderPoolDto>();
                orderPoolDto.AssignTimeOut = orderPool.AssignTimeOut;
                orderPoolDto.AssignStatus = orderPool.AssignStatus;
                orderPoolDto.Editer = orderPool.Editer;
                orderPoolDto.UpdateTime = orderPool.UpdateTime;
                orderPoolDto.EndTime = orderPool.EndTime;
                orderPoolDto.IsTimeOut = orderPool.IsTimeOut;
                orderPoolDto.TimeOutLevel = orderPool.TimeOutLevel;
                orderPoolDto.AssignEditerId = orderPool.AssignEditerId;
                orderPoolDto.DriverName = orderPool.DriverName;
                orderPoolDto.DriverPhone = orderPool.DriverPhone;
                orderPoolDto.DriverId = orderPool.DriverId;
                orderPoolDto.VehicleNo = orderPool.VehicleNo;
                if (orderPoolDto.Distance.HasValue)
                {
                    orderPoolDto.Distance = Math.Round(orderPoolDto.Distance.Value / 1000, 2, MidpointRounding.AwayFromZero);
                }
                orderPools.Add(orderPoolDto);
            }
            return new PageableList<OrderPoolDto>()
            {
                Items = orderPools,
                Count = entities.Item2
            };
        }

        private void RemoveOrderCache(long orderId)
        {
            string key = string.Format("{0}:OrderId={1}", EntityNameConst.OrderEntity, orderId);
            this.redisService.DeleteAsync(key);
            OrderDto order = this.GetOrder(orderId);
            key = string.Format("{0}:OrderNo={1}", EntityNameConst.OrderEntity, order.OrderNo);
            this.redisService.DeleteAsync(key);
            //key = string.Format("{0}:OrderNo={1}", EntityNameConst.OrderInfoFeeRecordEntity, order.OrderNo);
            //this.redisService.DeleteAsync(key);
            key = string.Format("{0}:OrderNo={1}", EntityNameConst.OrderExtentionEntities, order.OrderNo);
            this.redisService.DeleteAsync(key);
            order = this.GetOrder(orderId);
        }

        public OrderPoolDto ReceiveOrderAssign(DriverDto driver, long orderId)
        {
            var orderEntity = this.orderData.GetEntity(orderId).Result;

            if (orderEntity == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            var orderPool = this.orderPoolData.Get(orderId).GetAwaiter().GetResult();
            if (orderPool.DriverId != driver.DriverId)
            {
                throw new ArgumentException("无权接受他人的订单");
            }
            if (orderPool.AssignStatus == OrderAssignHandleStatus.Pending)
            {
                throw new ArgumentException("订单还未指派，不能接单");
            }
            if (orderPool.AssignStatus == OrderAssignHandleStatus.Done)
            {
                throw new ArgumentException("订单已处理完成，不能接单");
            }
            OrderStatus[] orderStatuses = new OrderStatus[] { OrderStatus.Cancel, OrderStatus.Acceptance, OrderStatus.Arrived, OrderStatus.Complete, OrderStatus.Pickup, OrderStatus.Transporting };
            if (orderEntity.OrderStatus.In(orderStatuses))
            {
                this.CloseOrder(orderId);
                throw new ArgumentException(string.Format("订单编号:{0}，司机已接单，无法接单!", orderEntity.OrderNo));
            }
            //更新订单的状态、司机信息
            this.database.BeginTransaction();

            if (!this.orderData.UpdateOrderDriver(orderEntity.OrderId, driver.DriverId, driver.Name, driver.Phone, driver.VehicleNo).GetAwaiter().GetResult())
            {
                throw new ArgumentException("接单失败。");
            }
            if (!this.orderAssignRecordData.UpdateOrderReceivedAsync(orderEntity.OrderId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("接单失败。");
            }

            if (!this.orderPoolData.UpdateOrderReceived(orderEntity.OrderId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("接单失败。");
            }

            if (!this.orderExtentionService.UpdateOrderStatusPickup(orderEntity.OrderNo))
            {
                throw new ArgumentException("接单失败。");
            }
            this.database.Commit();
            this.redisService.DeleteAsync(string.Format("{0}:OrderId={1}", EntityNameConst.OrderEntity, orderId));
            //推送
            this.pushMessageSendService.PushMessageForOrder(orderId, PushMessageType.BoundVehicleDistince);
            return this.GetOrder(orderEntity.OrderId);
        }
    }
}
